home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DJGPP / BCCGRX12.ZIP / contrib / bcc2grx / src / bccgrx06.c < prev    next >
C/C++ Source or Header  |  1993-07-23  |  12KB  |  467 lines

  1. /*
  2.  *  BCC2GRX  -  Interfacing Borland based graphics programs to LIBGRX
  3.  *  Copyright (C) 1993  Hartmut Schirmer
  4.  *
  5.  *  see bccgrx.c for details
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <ctype.h>
  12.  
  13. typedef unsigned char  uchar;
  14. typedef   signed char  schar;
  15. typedef unsigned short ushort;
  16.  
  17. #include <unistd.h>
  18. #include "bccgrx00.h"
  19.  
  20. #define FirstUserFont    11
  21. #define LastUserFont     (FirstUserFont+9)
  22. #define FirstGrxFont     (LastUserFont+1)
  23. #define LastGrxFont      (FirstGrxFont+9)
  24. #define NrFonts          (LastGrxFont+1)
  25. #define PreSkip          0x080
  26.  
  27. typedef struct {
  28.   unsigned short  width;
  29.   unsigned short *cmd;
  30. } CharInfo;
  31.  
  32. static int                      _height;
  33. static int                      _multx, _divx, _multy, _divy;
  34. static int _mult[11] = { 1, 3, 2, 3, 1, 4, 5, 2, 5, 3, 4};
  35. static int _div[11]  = { 1, 5, 3, 4, 1, 3, 3, 1, 2, 1, 1};
  36. static CharInfo                 CH[256];
  37. static void                    *Fonts[NrFonts];
  38. static struct textsettingstype  TXT;
  39. static GrTextOption             gr_Text;
  40.  
  41. static void do_init(void)
  42. {
  43.   static int Init = FALSE;
  44.   int i;
  45.  
  46.   if (Init) return;
  47.   for (i=0; i < NrFonts; ++i)
  48.     Fonts[i] = NULL;
  49.  
  50.   Fonts[DEFAULT_FONT] = (void *) GrLoadFont("@:pc8x8.fnt");
  51.   gr_Text.txo_font    = (GrFont *)Fonts[DEFAULT_FONT];
  52.   gr_Text.txo_chrtype = GR_BYTE_TEXT;
  53.  
  54.   TXT.font      = DEFAULT_FONT;
  55.   TXT.direction = HORIZ_DIR;
  56.   TXT.charsize  = 1;
  57.   TXT.horiz     = LEFT_TEXT;
  58.   TXT.vert      = TOP_TEXT;
  59.   _multx=_multy =
  60.   _divx = _divy = 1;
  61.   Init = TRUE;
  62. }
  63.  
  64.  
  65. static int _installgrxfont(int start, int stop, char *name)
  66. {
  67.   do_init();
  68.   while (start < stop && Fonts[start] != NULL) ++start;
  69.   if (start >= stop)
  70.     return grNoFontMem;
  71.   Fonts[start] = (void *) GrLoadFont(name);
  72.   if (Fonts[start] == NULL)
  73.     return grFontNotFound;
  74.   return start;
  75. }
  76.  
  77.  
  78. static int SetFont(void *font)
  79. {
  80.   uchar  *Header;
  81.   short  *sp;
  82.   char   *cp, *cd;
  83.   int    nrch, fstch, lastch, i;
  84.  
  85.  
  86.   if (font == NULL)
  87.     return FALSE;
  88.  
  89.   Header = (uchar *)font + PreSkip;
  90.   if ( memcmp( font, "PK\x8\x8", 4)!=0 || *(Header++) != '+')
  91.     return FALSE;
  92.  
  93.   for (i=0; i < 256; ++i) {
  94.     CH[i].width = 0;
  95.     CH[i].cmd   = NULL;
  96.   }
  97.  
  98.   nrch    = *(short *)Header;
  99.   Header  += 3;
  100.   fstch   = *(Header++);
  101.   lastch  = fstch + nrch;
  102.   cd      = ((char *)font) + PreSkip + *(short *)Header;
  103.   Header += 3;
  104.   _height = *Header;
  105.   Header += 2;
  106.   _height -= *((schar *)Header);
  107.  
  108.   cp      = cd - nrch;                 /* -> width table */
  109.   sp      = (short *) (cp - 2*nrch);   /* -> offset table */
  110.  
  111.   for (i=fstch; i < lastch; ++i)
  112.     CH[i].width = *(cp++);
  113.   for (i=fstch; i < lastch; ++i)
  114.     CH[i].cmd = (ushort *) (cd + sp[i-fstch]);
  115.   return TRUE;
  116. }
  117.  
  118. static char *StdFonts[BOLD_FONT+1] = {
  119.   "", "TRIP.CHR", "LITT.CHR", "SANS.CHR", "GOTH.CHR", "SCRI.CHR",
  120.       "SIMP.CHR", "TSCR.CHR", "LCOM.CHR", "EURO.CHR", "BOLD.CHR" };
  121.  
  122. static int _registerfont( int start, int stop, void *font)
  123. {
  124.   int    i;
  125.   char  *Header;
  126.   char  *name;
  127.  
  128.   do_init();
  129.   Header = (char *)font + PreSkip;
  130.   if ( memcmp( font, "PK\x8\x8",4)!=0 || *Header != '+')
  131.     return grInvalidFont;
  132.  
  133.   name = (char *) font;
  134.   while (*name != '\x1a') {
  135.     if ( name-(char *)font > 128)
  136.       return grInvalidFont;
  137.     ++name;
  138.   }
  139.   name += 3;
  140.  
  141.   for (i=1; i <= BOLD_FONT; ++i)
  142.     if (memcmp( name, StdFonts[i], 4) == 0)
  143.       break;
  144.   if (i > BOLD_FONT) {
  145.     i = start;
  146.     while ( i <= stop && Fonts[i] != NULL)
  147.       ++i;
  148.     if (i > stop)
  149.       return grNoFontMem;
  150.   }
  151.   Fonts[i] = font;
  152.   return i;
  153. }
  154.  
  155. static int _installfont( int start, int stop, char *name)
  156. {
  157.   FILE *ff;
  158.   long  size;
  159.   void *font;
  160.   int   res;
  161.  
  162.   ff = fopen( name, "rb");
  163.   if (ff == NULL)
  164.     return grFileNotFound;
  165.   fseek( ff, 0, SEEK_END);
  166.   size = ftell(ff);
  167.   fseek( ff, 0, SEEK_SET);
  168.   font = malloc( (size_t) size);
  169.   if (font == NULL) {
  170.     fclose( ff);
  171.     return grNoFontMem;
  172.   }
  173.   fread( font, (size_t) size, 1, ff);
  174.   fclose( ff);
  175.   res = _registerfont(start, stop, font);
  176.   if (res < 0)
  177.     free( font);
  178.   return res;
  179. }
  180.  
  181. int registerbgifont(void *font)
  182. {
  183.   return _registerfont( FirstUserFont, LastUserFont, font);
  184. }
  185.  
  186. int installuserfont(char *name)
  187. {
  188.   char *loc_name;
  189.  
  190.   loc_name = alloca(strlen(name)+1);
  191.   if (loc_name != NULL) {
  192.     strcpy(loc_name, name);
  193.     strlwr( loc_name);
  194.     if (strstr(loc_name, ".fnt") != 0)
  195.       return _installgrxfont( FirstGrxFont, LastGrxFont, name);
  196.   }
  197.   return _installfont( FirstUserFont, LastUserFont, name);
  198. }
  199.  
  200. /* ----------------------------------------------------------------- */
  201.  
  202. int textheight(char *textstring)
  203. {
  204.   _DO_INIT_CHECK_RV(0);
  205.   do_init();
  206.   if (TXT.font == DEFAULT_FONT)
  207.     return TXT.charsize * 8;
  208.   if (TXT.font >= FirstGrxFont && TXT.font <= LastGrxFont) {
  209.     gr_Text.txo_font = (GrFont *)Fonts[TXT.font];
  210.     gr_Text.txo_direct = GR_TEXT_RIGHT;
  211.     return GrStringHeight(textstring, strlen(textstring), &gr_Text);
  212.   }
  213.   return _height * _multy / _divy;
  214. }
  215.  
  216. /* ----------------------------------------------------------------- */
  217. int textwidth(char *textstring)
  218. {
  219.   int sum;
  220.  
  221.   _DO_INIT_CHECK_RV(0);
  222.   do_init();
  223.   if (TXT.font == DEFAULT_FONT)
  224.     return strlen(textstring) * TXT.charsize * 8;
  225.   if (TXT.font >= FirstGrxFont && TXT.font <= LastGrxFont) {
  226.     gr_Text.txo_font = (GrFont *)Fonts[TXT.font];
  227.     gr_Text.txo_direct = GR_TEXT_RIGHT;
  228.     return GrStringWidth(textstring, strlen(textstring), &gr_Text);
  229.   }
  230.   sum = 0;
  231.   while (*textstring != '\0')
  232.     sum += CH[*((uchar *)textstring++)].width * _multx / _divx;
  233.   return sum;
  234. }
  235.  
  236. /* ----------------------------------------------------------------- */
  237. inline static int xoff(ushort x)
  238. {
  239.   x &= 0x7f;
  240.   if (x < 0x40) return x;
  241.        else return (int) ((signed char)(x | 0xc0));
  242. }
  243.  
  244. inline static int yoff(ushort y)
  245. {
  246.   return -xoff( y >> 8);
  247. }
  248.  
  249. /* ----------------------------------------------------------------- */
  250. static void _otxt_vec(int *xx, int *yy, int XX, int YY, uchar *textstring)
  251. {
  252.   if (TXT.direction == HORIZ_DIR) {
  253.     int     _XX, x, y, nx, ny, w;
  254.     ushort *dc;
  255.  
  256.     switch (TXT.horiz) {
  257.       case CENTER_TEXT : XX -= textwidth(textstring) / 2; break;
  258.       case RIGHT_TEXT  : XX -= textwidth(textstring);     break;
  259.       default          : break;
  260.     }
  261.     switch (TXT.vert) {
  262.       case CENTER_TEXT : YY += textheight(textstring) / 2; break;
  263.       case TOP_TEXT    : YY += textheight(textstring);     break;
  264.       default          : break;
  265.     }
  266.     _XX = XX;
  267.     x = y = 0;
  268.     while (*textstring != '\0') {
  269.       w  = CH[*textstring].width;
  270.       dc = CH[*(textstring++)].cmd;
  271.       while (dc != NULL) {
  272.     switch ( *dc & 0x8080) {
  273.       case 0x0000 : dc = NULL;
  274.             XX += w * _multx / _divx;
  275.             break;
  276.       case 0x8000 : /* ... */
  277.             ++dc;
  278.             break;
  279.       case 0x0080 : x = xoff(*dc) * _multx / _divx;
  280.             y = yoff(*dc) * _multy / _divy;
  281.             ++dc;
  282.             break;
  283.       case 0x8080 : nx = xoff(*dc) * _multx / _divx;
  284.             ny = yoff(*dc) * _multy / _divy;
  285.             GrLine( XX+x, YY+y, XX+nx, YY+ny, COL);
  286.             x = nx;
  287.             y = ny;
  288.             ++dc;
  289.             break;
  290.     }
  291.       }
  292.     }
  293.     *xx += XX-_XX;
  294.   } else {
  295.     int     _YY, x, y, nx, ny, w;
  296.     ushort *dc;
  297.  
  298.     switch (TXT.horiz) {
  299.       case LEFT_TEXT   : XX += textheight(textstring);     break;
  300.       case CENTER_TEXT : XX += textheight(textstring) / 2; break;
  301.       default          : break;
  302.     }
  303.     switch (TXT.vert) {
  304.       case CENTER_TEXT : YY += textwidth(textstring) / 2; break;
  305.       case TOP_TEXT    : YY += textwidth(textstring);     break;
  306.       default          : break;
  307.     }
  308.     _YY = YY;
  309.     x = y = 0;
  310.     while (*textstring != '\0') {
  311.       w  = CH[*textstring].width;
  312.       dc = CH[*(textstring++)].cmd;
  313.       while (dc != NULL) {
  314.     switch ( *dc & 0x8080) {
  315.       case 0x0000 : dc = NULL;
  316.             YY -= w * _multx / _divx;
  317.             break;
  318.       case 0x8000 : /* ... */
  319.             ++dc;
  320.             break;
  321.       case 0x0080 : y = -xoff(*dc) * _multx / _divx;
  322.             x =  yoff(*dc) * _multy / _divy;
  323.             ++dc;
  324.             break;
  325.       case 0x8080 : ny = -xoff(*dc) * _multx / _divx;
  326.             nx =  yoff(*dc) * _multy / _divy;
  327.             GrLine( XX+x, YY+y, XX+nx, YY+ny, COL);
  328.             x = nx;
  329.             y = ny;
  330.             ++dc;
  331.             break;
  332.     }
  333.       }
  334.     }
  335.     *yy -= YY-_YY;
  336.   }
  337. }
  338.  
  339. /* ----------------------------------------------------------------- */
  340. static void _otxt_bit(int *xx, int *yy, int XX, int YY, uchar *txt)
  341. {
  342.   int len;
  343.  
  344.   gr_Text.txo_font      = (GrFont *)Fonts[TXT.font];
  345.   gr_Text.txo_xmag      =
  346.   gr_Text.txo_ymag      = TXT.charsize;
  347.   gr_Text.txo_fgcolor.v = COL;
  348.   gr_Text.txo_bgcolor.v = GrNOCOLOR;
  349.   gr_Text.txo_direct    = (TXT.direction == HORIZ_DIR) ? GR_TEXT_RIGHT:GR_TEXT_UP;
  350.   switch (TXT.horiz) {
  351.     case LEFT_TEXT   : gr_Text.txo_xalign = GR_ALIGN_LEFT;   break;
  352.     case RIGHT_TEXT  : gr_Text.txo_xalign = GR_ALIGN_RIGHT;  break;
  353.     case CENTER_TEXT :
  354.     default          : gr_Text.txo_xalign = GR_ALIGN_CENTER; break;
  355.   }
  356.   switch (TXT.vert) {
  357.     case BOTTOM_TEXT : gr_Text.txo_yalign = GR_ALIGN_BOTTOM; break;
  358.     case TOP_TEXT    : gr_Text.txo_yalign = GR_ALIGN_TOP;    break;
  359.     case CENTER_TEXT :
  360.     default          : gr_Text.txo_yalign = GR_ALIGN_CENTER; break;
  361.   }
  362.   len = strlen(txt);
  363.   GrDrawString( txt, len, XX, YY, &gr_Text);
  364.   if (TXT.direction == HORIZ_DIR)
  365.     *xx += GrStringWidth(txt, len, &gr_Text);
  366.   else {
  367.     gr_Text.txo_direct = GR_TEXT_RIGHT;
  368.     *yy -= GrStringWidth(txt,len, &gr_Text);
  369.   }
  370. }
  371.  
  372. /* ----------------------------------------------------------------- */
  373. static void _outtextxy(int *xx, int *yy, int XX, int YY, uchar *textstring)
  374. {
  375.   _DO_INIT_CHECK;
  376.   do_init();
  377.   if (TXT.font==DEFAULT_FONT || (TXT.font>=FirstGrxFont && TXT.font<=LastGrxFont))
  378.     _otxt_bit(xx,yy,XX,YY,textstring);
  379.   else
  380.     _otxt_vec(xx,yy,XX,YY,textstring);
  381. }
  382.  
  383. /* ----------------------------------------------------------------- */
  384. void outtext( char *textstring)
  385. {
  386.   _outtextxy(&X, &Y, X+VL, Y+VT, (uchar *)textstring);
  387. }
  388.  
  389. /* ----------------------------------------------------------------- */
  390. void outtextxy(int x, int y, char *textstring)
  391. {
  392.   _outtextxy( &x, &y, x+VL, y+VT, (uchar *)textstring);
  393. }
  394.  
  395. /* ----------------------------------------------------------------- */
  396. void gettextsettings(struct textsettingstype  *texttypeinfo)
  397. {
  398.   _DO_INIT_CHECK;
  399.   do_init();
  400.   memcpy( texttypeinfo, &TXT, sizeof(TXT));
  401. }
  402.  
  403. /* ----------------------------------------------------------------- */
  404. void settextjustify(int horiz, int vert)
  405. {
  406.   _DO_INIT_CHECK;
  407.   do_init();
  408.   TXT.horiz = horiz;
  409.   TXT.vert  = vert;
  410. }
  411.  
  412. /* ----------------------------------------------------------------- */
  413. void settextstyle(int font, int direction, int charsize)
  414. {
  415.   _DO_INIT_CHECK;
  416.   do_init();
  417.   if (font < DEFAULT_FONT || font >= NrFonts ||
  418.       (font > BOLD_FONT && Fonts[font] == NULL)) {
  419.     ERR = grInvalidFontNum;
  420.     return;
  421.   }
  422.   if (charsize < 0)  charsize = 0;
  423.   if (charsize > 10) charsize = 10;
  424.  
  425.   if (font != DEFAULT_FONT && (font<FirstGrxFont || font > LastGrxFont)) {
  426.     if (Fonts[font] == NULL) {
  427.       char fn[256], *cp;
  428.  
  429.       strcpy(fn, (__gr_BGICHR != NULL ? __gr_BGICHR : ".\\"));
  430.       cp = fn;
  431.       while ( *cp != '\0') ++cp;
  432.       if ( *(--cp) != '\\') {
  433.     *(++cp) = '\\';
  434.     *(cp+1) = '\0';
  435.       }
  436.       strcat( fn, StdFonts[font]);
  437.       _installfont( font, font, fn);
  438.     }
  439.     if (!SetFont( Fonts[font]))
  440.       font = DEFAULT_FONT;
  441.   }
  442.   TXT.font         = font;
  443.   TXT.direction    = direction;
  444.   TXT.charsize     = charsize;
  445.   _multx = _multy  = _mult[charsize];
  446.   _divx  = _divy   = _div[charsize];
  447. }
  448.  
  449.  
  450. /* ----------------------------------------------------------------- */
  451. void setusercharsize(int multx, int divx, int multy, int divy)
  452. {
  453.   _DO_INIT_CHECK;
  454.   do_init();
  455.   if (divx == 0 || divy == 0 || TXT.font == DEFAULT_FONT) {
  456.     ERR = grError;
  457.     return;
  458.   }
  459.   TXT.charsize = 0;
  460.   _multx = multx;
  461.   _divx  = divx;
  462.   _multy = multy;
  463.   _divy  = divy;
  464. }
  465.  
  466.  
  467.